﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Web;

namespace SharePointAccessMonitor.Models
{
    public class LogItem
    {
        public DateTime Timestamp { get; set; }
        public string User { get; set; }
        public string Title { get; set; }
        public string Url { get; set; }
        public string AddInfo { get; set; }

        private Dictionary<string, string> addInfos;

        private NameValueCollection queryInfos;
        private string EscapedTitle
        {
            get
            {
                if (Title == null) return null;
                return Title.Replace(",", "，");
            }
        }

        public string GetAddInfo(string key)
        {
            if (addInfos == null)
            {
                if (AddInfo == null) return null;
                addInfos = new Dictionary<string, string>();
                foreach (var item in AddInfo.Split('&'))
                {
                    var keyVal = item.Split('=');
                    addInfos.Add(keyVal[0], keyVal.Length <= 1 ? "" : keyVal[1]);
                }
            }
            if (addInfos.ContainsKey(key)) return addInfos[key];
            return null;
        }

        public string GetQueryInfo(string key)
        {
            if (queryInfos == null)
            {
                var idx = Url.IndexOf('?');
                if (idx >= 0)
                {
                    var queryString = Url.Substring(idx).Split('#')[0];
                    queryInfos = System.Web.HttpUtility.ParseQueryString(queryString);
                }
                else
                {
                    return null;
                }
            }
            return queryInfos[key];
        }

        private string GetAbsolutePath(string url)
        {
            if (Url.StartsWith("http"))
            {
                var uri = new Uri(Url);
                url = HttpUtility.UrlDecode(uri.AbsolutePath + uri.Fragment);
            }
            return url.Split('?')[0];
        }
        public List<string> GetDoumentPath()
        {
            List<string> filePaths = new List<string>();
            var action = GetActionPage();
            if (GetAddInfo("r") == "n" && !action.EndsWith(".aspx"))
            {
                var f = GetAbsolutePath(Url);
                filePaths.Add(f);

            }
            if (action == "upload.aspx")
            {
                for (int i=0; ;i++)
                {
                    var file = GetAddInfo("f" + i.ToString());
                    if (file == null) break;
                    file = HttpUtility.UrlDecode(GetAddInfo("RootFolder")) + "/" + file;
                    filePaths.Add(file);
                }

            }
            if (action == "download.aspx")
            {
                var file = GetQueryInfo("SourceUrl");
                var pos = file.IndexOf("?");
                if (pos >= 0) file = file.Substring(0, pos);
                filePaths.Add(file);
            }
            return filePaths;
        }

        public string GetListUrl()
        {
            var pos = Url.IndexOf("/_layouts");
            string listUrl = Url;
            if (pos >= 0) listUrl = Url.Substring(0, pos);
            pos = Url.IndexOf("#");
            if (pos >= 0) listUrl += Url.Substring(pos + 1);
            pos = listUrl.IndexOf('?');
            if (pos >= 0) listUrl = listUrl.Substring(0, pos);
            var action = GetActionPage();
            if (action.EndsWith(".aspx")) listUrl = listUrl.Substring(0, listUrl.Length - action.Length);
            return listUrl;
        }

        public string GetListItemPath()
        {
            var action = GetActionPage();
            if (action == "dispform.aspx")
            {
                var path = GetListUrl();
                return path + "?ID=" + GetQueryInfo("ID");

            }
            else
            {
                return null;
            }
        }

        public string GetDisccusionPath()
        {
            var action = GetActionPage();
            if (action == "flat.aspx" || action == "management.aspx")
            {
                var path = GetListUrl();
                return HttpUtility.HtmlDecode(GetQueryInfo("RootFolder"));

            }
            else
            {
                return null;
            }
        }

        public string GetActionPage()
        {
            var f = GetAbsolutePath(Url);
            return Path.GetFileName(f).ToLower();
        }

        public string GetSummary()
        {
            var shortUrl = Url;
            if (Url.StartsWith("http"))
            {
                var uri = new Uri(Url);
                shortUrl = HttpUtility.UrlDecode(uri.PathAndQuery);
            }
            return string.Format("{0} ({1})", Title, shortUrl);
        }
        public override string ToString()
        {
            return Timestamp.ToString(dateFormat) + "," + (User ?? "") + "," + Url + "," + (EscapedTitle ?? "") + "," +AddInfo;
        }

        private const string dateFormat = "yyyy/MM/dd HH:mm:ss fff";
        public static LogItem Parse(string line)
        {
            var items = line.Split(',');
            var ret = new LogItem();

            ret.Timestamp = DateTime.ParseExact(items[0], dateFormat, null);
            ret.User = items[1];
            ret.Url = items[2];
            ret.Title = items[3];
            ret.AddInfo = string.Join(",", items.Skip(4));
            return ret;
        }

    }
}